// sm2_gmssl.c
#include <stdio.h>
#include <string.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>

#define SM2_NUMWORD 32

// SM2标准曲线参数（与国标一致）
unsigned char SM2_std_priKey[32] = {
    0x39,0x45,0x20,0x8F,0x7B,0x21,0x44,0xB1,0x3F,0x36,0xE3,0x8A,0xC6,0xD3,0x9F,0x95,
    0x88,0x93,0x93,0x69,0x28,0x60,0xB5,0x1A,0x42,0xFB,0x81,0xEF,0x4D,0xF7,0xC5,0xB8
};

unsigned char SM2_std_pubKey[64] = {
    0x09,0xF9,0xDF,0x31,0x1E,0x54,0x21,0xA1,0x50,0xDD,0x7D,0x16,0x1E,0x4B,0xC5,0xC6,
    0x72,0x17,0x9F,0xAD,0x18,0x33,0xFC,0x07,0x6B,0xB0,0x8F,0xF3,0x56,0xF3,0x50,0x20,
    0xCC,0xEA,0x49,0x0C,0xE2,0x67,0x75,0xA5,0x2D,0xC6,0xEA,0x71,0x8C,0xC1,0xAA,0x60,
    0x0A,0xED,0x05,0xFB,0xF3,0x5E,0x08,0x4A,0x66,0x32,0xF6,0x07,0x2D,0xA9,0xAD,0x13
};

unsigned char SM2_std_rand[32] = {
    0x59,0x27,0x6E,0x27,0xD5,0x06,0x86,0x1A,0x16,0x68,0x0F,0x3A,0xD9,0xC0,0x2D,0xCC,
    0xEF,0x3C,0xC1,0xFA,0x3C,0xDB,0xE4,0xCE,0x6D,0x54,0xB8,0x0D,0xEA,0xC1,0xBC,0x21
};

unsigned char SM2_std_Message[19] = {
    0x65,0x6E,0x63,0x72,0x79,0x70,0x74,0x69,0x6F,0x6E,0x20,0x73,0x74,0x61,0x6E,0x64,0x61,0x72,0x64
};

unsigned char SM2_std_Cipher[115] = {
    0x04,0xEB,0xFC,0x71,0x8E,0x8D,0x17,0x98,0x62,0x04,0x32,0x26,0x8E,0x77,0xFE,0xB6,
    0x41,0x5E,0x2E,0xDE,0x0E,0x07,0x3C,0x0F,0x4F,0x64,0x0E,0xCD,0x2E,0x14,0x9A,0x73,
    0xE8,0x58,0xF9,0xD8,0x1E,0x54,0x30,0xA5,0x7B,0x36,0xDA,0xAB,0x8F,0x95,0x0A,0x3C,
    0x64,0xE6,0xEE,0x6A,0x63,0x09,0x4D,0x99,0x28,0x3A,0xFF,0x76,0x7E,0x12,0x4D,0xF0,
    0x59,0x98,0x3C,0x18,0xF8,0x09,0xE2,0x62,0x92,0x3C,0x53,0xAE,0xC2,0x95,0xD3,0x03,
    0x83,0xB5,0x4E,0x39,0xD6,0x09,0xD1,0x60,0xAF,0xCB,0x19,0x08,0xD0,0xBD,0x87,0x66,
    0x21,0x88,0x6C,0xA9,0x89,0xCA,0x9C,0x7D,0x58,0x08,0x73,0x07,0xCA,0x93,0x09,0x2D,0x65,0x1E,0xFA
};

void print_hex(const char* label, const unsigned char* data, size_t len) {
    printf("%s: ", label);
    for (size_t i = 0; i < len; i++) {
        printf("%02x", data[i]);
    }
    printf("\n");
}

int SM2_Test_with_GmSSL() {
    SM2_KEY key;
    unsigned char ciphertext[256];
    unsigned char decrypted[256];
    size_t ciphertext_len, decrypted_len;
    int i;
    
    printf("=== SM2 Algorithm Test with GmSSL ===\n\n");
    
    // 1. 使用标准私钥设置SM2密钥
    printf("1. Setting up SM2 key from standard private key...\n");
    if (sm2_private_key_info_from_der(&key, SM2_std_priKey, sizeof(SM2_std_priKey)) != 1) {
        printf("Failed to set private key\n");
        return 1;
    }
    printf("✅ Private key set successfully\n");
    
    // 2. 加密标准测试数据
    printf("2. Encrypting standard test message...\n");
    printf("Original message: ");
    for (i = 0; i < 19; i++) {
        printf("%02x ", SM2_std_Message[i]);
    }
    printf("\n");
    
    if (sm2_encrypt(&key, SM2_std_Message, 19, ciphertext, &ciphertext_len) != 1) {
        printf("❌ Encryption failed\n");
        return 1;
    }
    printf("✅ Encryption successful\n");
    printf("Ciphertext length: %zu bytes\n", ciphertext_len);
    
    // 3. 解密
    printf("3. Decrypting ciphertext...\n");
    if (sm2_decrypt(&key, ciphertext, ciphertext_len, decrypted, &decrypted_len) != 1) {
        printf("❌ Decryption failed\n");
        return 1;
    }
    
    printf("Decrypted message: ");
    for (i = 0; i < decrypted_len; i++) {
        printf("%02x ", decrypted[i]);
    }
    printf("\n");
    
    // 4. 验证
    printf("4. Verification...\n");
    if (memcmp(SM2_std_Message, decrypted, 19) == 0 && decrypted_len == 19) {
        printf("✅ SM2 Test: PASS - Encryption/Decryption successful\n");
    } else {
        printf("❌ SM2 Test: FAIL\n");
        return 1;
    }
    
    return 0;
}

int SM2_KeyGen_Test() {
    SM2_KEY key;
    unsigned char msg[] = "Hello SM2 Key Generation Test";
    unsigned char ciphertext[256];
    unsigned char decrypted[256];
    size_t ciphertext_len, decrypted_len;
    
    printf("\n=== SM2 Key Generation Test ===\n");
    
    // 生成新的SM2密钥对
    printf("1. Generating new SM2 key pair...\n");
    if (sm2_key_generate(&key) != 1) {
        printf("❌ Key generation failed\n");
        return 1;
    }
    printf("✅ New key pair generated successfully\n");
    
    // 加密测试
    printf("2. Encrypting test message...\n");
    printf("Message: %s\n", msg);
    
    if (sm2_encrypt(&key, msg, strlen((char*)msg), ciphertext, &ciphertext_len) != 1) {
        printf("❌ Encryption failed\n");
        return 1;
    }
    printf("✅ Encryption successful (%zu bytes)\n", ciphertext_len);
    
    // 解密测试
    printf("3. Decrypting...\n");
    if (sm2_decrypt(&key, ciphertext, ciphertext_len, decrypted, &decrypted_len) != 1) {
        printf("❌ Decryption failed\n");
        return 1;
    }
    
    decrypted[decrypted_len] = '\0';
    printf("Decrypted: %s\n", decrypted);
    
    if (memcmp(msg, decrypted, strlen((char*)msg)) == 0) {
        printf("✅ Key Generation Test: PASS\n");
    } else {
        printf("❌ Key Generation Test: FAIL\n");
        return 1;
    }
    
    return 0;
}

int main() {
    printf("SM2 Algorithm Implementation Test\n");
    printf("=================================\n\n");
    
    // 测试1: 使用标准密钥
    if (SM2_Test_with_GmSSL() != 0) {
        return 1;
    }
    
    // 测试2: 密钥生成测试
    if (SM2_KeyGen_Test() != 0) {
        return 1;
    }
    
    printf("\n🎉 All SM2 tests completed successfully!\n");
    printf("✅ SM2 algorithm is working correctly with GmSSL\n");
    
    return 0;
}
